package com.lyf.network.practice.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

/**
 * @author LYF
 * @date 2022/6/24
 */
public class SelectorTests {

    SocketChannel socketChannel;


    /**
     NioServer
     */
    @Test
    public  void startServer() throws IOException {
        // 1.开启选择器
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(
        );
        // 3.设置非阻塞模式
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8899));
        // 注册到选择器
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //serverSocketChannel.register(selector,SelectionKey.OP_WRITE);

        System.out.println("INFO: Start Server Ok...");

        while(selector.select()>0){

            Set<SelectionKey> selectionKeySet = selector.selectedKeys();
            Iterator<SelectionKey> selectorKeyIterator = selectionKeySet.iterator();

            while(selectorKeyIterator.hasNext()){

                SelectionKey key = selectorKeyIterator.next();

                if(key.isAcceptable()){
                    //

                    SocketChannel accept = serverSocketChannel.accept();

                    System.out.println("accept...:::"+accept);

                    accept.configureBlocking(false);

                    accept.register(selector,SelectionKey.OP_READ);

                    // 监听的channel状态--
                }else if(key.isReadable()){
                    System.out.println("read...");
                    SocketChannel socketChannel = (SocketChannel) key.channel();

                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    socketChannel.read(buffer);
                    buffer.flip();
                    String content = new String(buffer.array());
                    System.out.println(content);//new String(buffer.array())
                    buffer.clear();

                    // 可根据 buffer发送来的内容进行分发--
                    // buffer(制定协议):   handle_mode -- (server_handle,push_person,push_group)
                    // 策略模式--？不同模式不同行为
                    // 可设计为json格式， selector则为监听到的状态情况（所有通道）

                    String replyContent ="default..";
                    String[] strings = content.split("\\;");// 自定义标准   mode;args;
                    if(strings[0].equals("server_handle")){
                        String [] reply = {"hello1","hello2"};
                        replyContent=reply[new Random().nextInt(2)];
                        socketChannel.write(Charset.forName("UTF-8").encode(replyContent));
                    }else{
                        // no_handle
                    }

                    // 往回写
                    this.socketChannel = socketChannel;

                }

                selectorKeyIterator.remove();
            }


        }


//        for(;;){// 底层比while更优
//
//            int selection = selector.select();
//
//            System.out.println("注册--selection-"+selection);
//
//            Set<SelectionKey> selectionKeySet = selector.selectedKeys();
////            System.out.println(selectionKeySet);
//
//            for (SelectionKey key:selectionKeySet){
//
//                if(key.isAcceptable()){// 接入
//                    System.out.println("accept...");
//
//                    SocketChannel socketChannel =  serverSocketChannel.accept();// non-blocking
//
//                    socketChannel.configureBlocking(false);
//
//                    System.out.println("Client-"+socketChannel.getRemoteAddress()+"connected...");
//
//                    socketChannel.register(selector,SelectionKey.OP_READ);
//
//                }else if(key.isReadable()){
//                    System.out.println("read...");
//                    //key.channel();
////                    SocketChannel socketChannel = (SocketChannel) key.channel();
////                    ByteBuffer buffer=ByteBuffer.allocate(10);
////
////
////                    socketChannel.read(buffer);
////
//                 //     buffer.flip();
//
////                    System.out.println(new String(buffer.array()));
//
//                }
//
//                // 需要移除此次连接的--
//                selectionKeySet.remove(key);
//            }
//
//
//
//        }

    }

    /***

     */


    /**
     NioClient
     */
//    @Test
//    public void startClient() throws IOException{
//        SocketChannel socketChannel= SocketChannel.open(new InetSocketAddress("127.0.0.1",8899));
//        socketChannel.configureBlocking(false);
//        socketChannel.write(Charset.forName("UTF-8").encode("hello"));
//    }

    public static void startClient() throws IOException {
        SocketChannel socketChannel= SocketChannel.open(new InetSocketAddress("127.0.0.1",8899));
        socketChannel.configureBlocking(false);
        Scanner scanner = new Scanner(System.in);
        while(true){
            String str = scanner.nextLine();
            socketChannel.write(Charset.forName("UTF-8").encode(str));

            ByteBuffer buffer = ByteBuffer.allocate(1024);
            socketChannel.read(buffer);
            buffer.flip();
            System.out.println(new String(buffer.array()));
        }
    }

    public static void main(String[] args) throws IOException {

        // 模拟十个用户
//        new Thread(()->{
//
//        }).start();
          startClient();
    }

}
